#pragma once
#include "funcbase.h"

namespace KRPC {

template<typename>
class SyncFunc;

template<typename R, typename ... Args>
class SyncFunc<R(Args...)> : public FuncBase
{	//针对返回参数是非void
public:
	SyncFunc(std::string funcname, COM &com, int timeoutMsec) : \
		FuncBase(com), name(std::move(funcname)), msec(timeoutMsec) 
	{
		assert(name.size() < MAX_RPCNAME_LEN);
	}
		
	Optional<R> operator()(Args... args)
	{
		R ret;
		return (send(name, RPC_REQ, std::forward<Args>(args)...) 
				&& recv(ret, RPC_REP, msec)) ? Optional<R>(std::move(ret)) : nullptr;
	}
private:
	std::string name;
	int msec;	//接收超时秒数
};

template<typename ... Args>
class SyncFunc<void(Args...)> : public FuncBase
{	//针对返回参数是非void
public:
	SyncFunc(std::string funcname, COM &com, int timeoutMsec) : \
		FuncBase(com), name(std::move(funcname)), msec(timeoutMsec) 
	{
		assert(name.size() < MAX_RPCNAME_LEN);
	}

	Optional<void> operator()(Args... args)
	{
		return (send(name, RPC_REQ, std::forward<Args>(args)...) && recv(RPC_REP, msec));
	}
private:
	std::string name;
	int msec;	//接收超时秒数
};

} //end of namespace KRPC
